/**
 * 
 */
package cn.springsoter.core.security.strategy.impl;

import java.io.FileNotFoundException;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.google.common.collect.Maps;

import cn.hutool.core.util.CharsetUtil;
import cn.springsoter.core.security.constant.SecurityConstant;
import cn.springsoter.core.security.props.SecurityProperties;
import cn.springsoter.core.security.strategy.ReadKeyStrategy;
import cn.springsoter.core.tool.utils.FileUtil;
import cn.springsoter.core.tool.utils.KeyStoreUtil;
import cn.springsoter.core.tool.utils.RSAUtil;
import cn.springsoter.core.tool.utils.SpringUtil;

/**
 * 从keystore读取AES key
 * 
 * @author kevin
 *
 */
@Service
public class ReadAESKeyStoreStrategy implements ReadKeyStrategy {

	private static final String AES_KEY_STORE_CACHE = "AES_KEY_STORE";
	private static Map<String, String> KEY_MAP = Maps.newConcurrentMap();
	
	@Override
	public String readKey() throws Exception{
		String key = KEY_MAP.get(AES_KEY_STORE_CACHE);
		if(StringUtils.isBlank(key)) {
			
			SecurityProperties securityProperties = null;
			try {
				securityProperties = SpringUtil.getBean("securityProperties");
			} catch(Exception e) {
			}
			
			if(Objects.nonNull(securityProperties) 
					&& StringUtils.isNotBlank(securityProperties.getPassword()) 
					&& StringUtils.isNotBlank(securityProperties.getAppName())
					&& StringUtils.isNotBlank(securityProperties.getKeystorePath())) { //先判断keystore是否有密钥
				
				String aesAlias = String.format(SecurityConstant.AES_ALIAS, securityProperties.getAppName());
		    	String rsaPrivateAlias = String.format(SecurityConstant.RSA_PRIVATE_ALIAS, securityProperties.getAppName());
		    	
		        String aesPath = String.format(SecurityConstant.KEYSTORE_PATH, securityProperties.getKeystorePath(), aesAlias);
		        String privateKeyPath = String.format(SecurityConstant.KEYSTORE_PATH, securityProperties.getKeystorePath(), rsaPrivateAlias);
		        
		        boolean isAesExist = FileUtil.exist(aesPath);
		    	boolean isPrivateKeyExist = FileUtil.exist(privateKeyPath);
		    	
		    	if(!isAesExist || !isPrivateKeyExist) {
		    		throw new FileNotFoundException("file: RSA KeyStore file not exist!");
		    	}
		    	
		    	String encryptAesKey = KeyStoreUtil.getStoreKey(aesAlias, aesPath, securityProperties.getPassword());
		    	String privateKey = KeyStoreUtil.getStoreKey(rsaPrivateAlias, privateKeyPath, securityProperties.getPassword());
		    	
		    	key = RSAUtil.decryptByPrivateKey(encryptAesKey, RSAUtil.getPrivateKeyFromString(privateKey), CharsetUtil.UTF_8);
		    	KEY_MAP.put(AES_KEY_STORE_CACHE, key);
			}
		}
		return key;
	}

}
